package com.kaikai.commonutils;


import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider;

import java.io.IOException;
import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;

public class JsonUtil
{
    private static ObjectMapper objectMapper;

    static
    {
//        GsonBuilder gb = new GsonBuilder();
//        gb.setPrettyPrinting().disableHtmlEscaping().registerTypeAdapter(Timestamp.class, new TimestampTypeAdapter());
//        gb.setLongSerializationPolicy(LongSerializationPolicy.STRING);
//        gb.setDateFormat("yyyy-MM-dd HH:mm:ss");
//        gson = gb.create();
        DefaultSerializerProvider.Impl sp = new DefaultSerializerProvider.Impl();
        objectMapper = new ObjectMapper(null, sp, null);
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true);
    }

    public static Map convertJsonToMap(String jsonString)
    {
        try
        {
            return (Map)objectMapper.readValue(jsonString, Map.class);
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    public static String convertMapToJson(Map<String, Object> map)
    {
        try
        {
            return objectMapper.writeValueAsString(map);
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    public static <T> T convertJsonToObject(String jsonString, Class<T> modelCalss)
    {
        try
        {
            return (T)objectMapper.readValue(jsonString, modelCalss);
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    public static Map<String, String> getMap4Json(String jsonString)
    {
        try
        {
        return     (Map)convertJsonToObject(jsonString, new TypeReference() {});
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    public static Map<String, Object> getMap4JsonObject(String jsonString)
    {
        try
        {
          return  (Map)convertJsonToObject(jsonString, new TypeReference() {});
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    public static String getJsonValue(String jsonStr, String key)
    {
        try
        {
            JsonNode rootNode = objectMapper.readTree(jsonStr);
            JsonNode keyNode = rootNode.get(key);
            if (keyNode != null) {
                return keyNode.asText();
            }
            return null;
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    public static String convertObjectToJson(Object javaObj)
    {
        try
        {
            return objectMapper.writeValueAsString(javaObj);
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    public static <T> List<T> convertJsonToList(String jsonString, Class<T> pojoClass) throws IOException
    {
    	MappingIterator<T>  iterator=objectMapper.readerFor(pojoClass).readValues(jsonString);
    	List<T> list = iterator.readAll();
    	return list;
    }

    @Deprecated
    public static <T> T convertJsonToObject(String jsonString, Type typeofObject)
    {
        throw new RuntimeException("convertJsonToObject");
    }

    public static <T> T convertJsonToObject(String jsonString, TypeReference<?> typeReference)
    {
        try
        {
            return (T)objectMapper.readValue(jsonString, typeReference);
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }
}
